package com.coda.service.impl;

import com.coda.Constant.StatusConstant;
import com.coda.Properties.JwtProperties;
import com.coda.common.Result;
import com.coda.entity.LoginUser;
import com.coda.entity.User;
import com.coda.exception.BaseException;
import com.coda.mapper.UserMapper;
import com.coda.service.LoginService;
import com.coda.utils.JwtUtils;
import com.google.code.kaptcha.Producer;
import io.jsonwebtoken.Claims;
import jdk.nashorn.internal.parser.Token;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.HashMap;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class LoginServiceImpl implements LoginService {

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private Producer captcha;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private JwtProperties jwtProperties;

    /**
     * 生成图形验证码
     *
     * @param response
     */
    @Override
    public void setCaptcha(HttpServletResponse response) {

        //响应正文为jpg格式验证码图片
        response.setContentType("image/jpeg");
        //生成验证码文本
        String code = captcha.createText();
        //生成对应图片
        BufferedImage image = captcha.createImage(code);

        //将验证码存储redis中
        redisTemplate.opsForValue().set(code, code, 180, TimeUnit.SECONDS);


        ServletOutputStream out = null;
        try {
            //获取输出流
            out = response.getOutputStream();
            //将图片响应给前端
            ImageIO.write(image, "jpg", out);
            out.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            //释放资源
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }

    }

    /**
     * 登录
     *
     * @param loginUser
     * @return
     */
    @Override
    public String login(LoginUser loginUser) {
        //获取redis中存储的验证码
        String code = (String) redisTemplate.opsForValue().get(loginUser.getVerificationCode());
        //判断是否有用户名
        if (loginUser.getUserCode() == null) {
            throw new BaseException(Result.CODE_ERR_BUSINESS, "请输入用户名");
        }

        //判断是否有密码
        if (loginUser.getUserPwd() == null) {
            throw new BaseException(Result.CODE_ERR_BUSINESS, "请输入密码");
        }

        //判断是否有验证码
        if (loginUser.getVerificationCode() == null) {
            throw new BaseException(Result.CODE_ERR_BUSINESS, "请输入验证码");
        }

        //判断验证码是否正确
        if (!(loginUser.getVerificationCode().equals(code) )) {
            throw new BaseException(Result.CODE_ERR_BUSINESS, "验证码错误");
        }

        User user = userMapper.getUserByName(loginUser.getUserCode());
        //判断是否有用户
        if (user == null) {
            throw new BaseException(Result.CODE_ERR_BUSINESS, "该员工不存在");
        }

        //将请求中的验证码进行md5加密
        String password = DigestUtils.md5DigestAsHex(loginUser.getUserPwd().getBytes());
        //判断用户名和密码是否正确
        if (!(loginUser.getUserCode().equals(user.getUserCode()) && password.equals(user.getUserPwd()))) {
            throw new BaseException(Result.CODE_ERR_BUSINESS, "用户名或密码错误");
        }

        //判断当前员工状态
        if (user.getUserState().equals(StatusConstant.USER_STATE_NOT_PASS) ){
            throw new BaseException(Result.CODE_ERR_BUSINESS,"当前用户未审核");
        }

        //创建jwt令牌
        HashMap<String, Object> claims = new HashMap<>();
        claims.put("Id", user.getUserId());
        String token = JwtUtils.createJWT(
                jwtProperties.getSecretKey(),
                jwtProperties.getTtl(),
                claims);
        return token;
    }
}
